package com.hl.godsent.utils


import android.content.Context
import android.util.Base64
//import com.hl.godsent.BuildConfig
import com.hl.godsent.R
import java.io.BufferedInputStream
import java.io.IOException
import java.security.InvalidKeyException
import java.security.KeyFactory
import java.security.NoSuchAlgorithmException
import java.security.PublicKey
import java.security.spec.InvalidKeySpecException
import java.security.spec.X509EncodedKeySpec
import javax.crypto.BadPaddingException
import javax.crypto.Cipher
import javax.crypto.IllegalBlockSizeException
import javax.crypto.NoSuchPaddingException


object EncryptUtil {
    private const val TAG = "EncryptUtil"
    const val RSA = "RSA" // 非对称加密密钥算法
    const val ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding" //加密填充方式
    const val DEFAULT_KEY_SIZE = 4096 //秘钥默认长度
    val DEFAULT_SPLIT = "#PART#".toByteArray() // 当要加密的内容超过bufferSize，则采用partSplit进行分块加密
    const val DEFAULT_BUFFERSIZE = DEFAULT_KEY_SIZE / 8 - 11 // 当前秘钥支持加密的最大字节数
    private var publicKeyByte: ByteArray? = null
    private val privateKeyByte: ByteArray? = null
    fun sampleDecrypt() {
//        String rawLog = "tN7hjBvXhn8QMnjqJVF8GYzJE0o+sjLb3BiVuJpuqm0dlZ1mp0lCfSzZf5hu+f2ZLAsXh7UWAVCo\n" +
//                "d6xNpWx6dxnTnbEbLd02W4OmfzmmVwP8X2fOCjr2GkE3P1jh94jtb33nnzJq5mSR8C3yqwN9x9JN\n" +
//                "DbLJm13gZbUyFFz+mCpG/d+PGw7Gh+rt/wFwZS9Z6IkW25c03n+Gyjy6UDOvIzU1LgzTxBD4KRUs\n" +
//                "d2BG/sriI2fV6EHRg5qgW6TOPt/crOqceNM/qABZCSY+pUeK69WD31uh+ek4fPuL/o+Tq+R9cIuV\n" +
//                "/n1P2AjayDQa714QqqkbvB2Ti5T32Rk79Ms4fJuzpvyJ9CcAIl3SttsL1az7pq2NS7NodjqS5DfD\n" +
//                "l2XblGmV+orIdEbOrJE+1L9UTTX7nGBYyYH7LUFxkTcdCvgnbqkmOyRDFpTSddUc+FuA1y8eBNr6\n" +
//                "aV3M+2hWK7ICyQljf0qZBjb1cL9NwVolQHF8A58/w76c3Gj9n8a5wol+h9CiYio3O8pHTgwPe0Kl\n" +
//                "Odj+bctEUx+BkgRbxxi6KLrCVg0BC3kXsa5Ikqn21Gm3rNGpfir2hdNshS+aqXuFmeeGSLJ+OtwE\n" +
//                "pFTHUOL+g09MZ1zaJLuo4wNAyiipN3JnqHvDRg2W9LERRQRWUqwCrIdms//6eKi4Fpz6aUdYTB4=\n" +
//                "$$L$$";
//        String [] splits = rawLog.split("\\$\\$L\\$\\$");
//        for (String split : splits) {
//            byte[] bytes = Base64.decode(split, Base64.DEFAULT);
//            byte[] decryptedBytes = EncryptUtil.decryptV2(bytes);
//            CoreLog.i(TAG, "加密前字符串为：" + new String(decryptedBytes, Charset.defaultCharset()));
//        }
    }

    fun sampleEncryptAndDecrypt() {
//        byte[] bytes = "asdqwe1w爱t123😱123asds".getBytes();
//        byte[] encryptedBytes = EncryptUtil.encryptV2(bytes);
//        byte[] decryptedBytes = EncryptUtil.decryptV2(encryptedBytes);
//        CoreLog.i(TAG, "加密前字符串为：" + new String(decryptedBytes, Charset.defaultCharset()));
    }

    fun initialize(applicationContext: Context) {
        val inputStream = applicationContext.resources.openRawResource(R.raw.rsa_public)
        val bis = BufferedInputStream(inputStream)
        val buffer = ByteArray(1000)
        try {
            val readLength = bis.read(buffer, 0, 1000)
            if (readLength > 0) {
                val publicKeyByteTemp = ByteArray(readLength)
                System.arraycopy(buffer, 0, publicKeyByteTemp, 0, readLength)
                publicKeyByte = Base64.decode(publicKeyByteTemp, Base64.DEFAULT)

            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    private fun encryptUnit(data: ByteArray): ByteArray? {
        val keySpec = X509EncodedKeySpec(publicKeyByte)
        var kf: KeyFactory? = null
        try {
            kf = KeyFactory.getInstance(RSA)
            val key = kf.generatePublic(keySpec)
            // 数据加密
            val cipher = Cipher.getInstance(ECB_PKCS1_PADDING)
            cipher.init(Cipher.ENCRYPT_MODE, key)
            return cipher.doFinal(data)
        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        } catch (e: InvalidKeyException) {
            e.printStackTrace()
        } catch (e: InvalidKeySpecException) {
            e.printStackTrace()
        } catch (e: BadPaddingException) {
            e.printStackTrace()
        } catch (e: IllegalBlockSizeException) {
            e.printStackTrace()
        } catch (e: NoSuchPaddingException) {
            e.printStackTrace()
        }
        return null
    }

    //    public static byte[] decryptUnit(byte[] data) {
    //        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
    //        KeyFactory kf = null;
    //        try {
    //            kf = KeyFactory.getInstance(RSA);
    //
    //            PrivateKey keyPrivate = kf.generatePrivate(keySpec);
    //
    //            // 解密数据
    //            Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING);
    //            cp.init(Cipher.DECRYPT_MODE, keyPrivate);
    //            return cp.doFinal(data);
    //        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    fun encryptV2(data: ByteArray?): ByteArray? {
        if (data == null || data.size == 0) {
            return "".toByteArray()
        }
        val dataLength = data.size
        // 一次 单块加密就能完成
        if (dataLength <= DEFAULT_BUFFERSIZE) {
            return encryptUnit(data)
        }
        var blockCount = 0
        blockCount = if (dataLength % DEFAULT_BUFFERSIZE == 0) {
            dataLength / DEFAULT_BUFFERSIZE
        } else {
            dataLength / DEFAULT_BUFFERSIZE + 1
        }
        val result = ByteArray(blockCount * (DEFAULT_KEY_SIZE / 8))
        var resultCurrentPosition = 0
        // 分块加密
        var currentPosition = 0
        var bufferLength = 0
        while (currentPosition < dataLength) {
            bufferLength = Math.min(dataLength - currentPosition, DEFAULT_BUFFERSIZE)
            val buffer = ByteArray(bufferLength)
            System.arraycopy(data, currentPosition, buffer, 0, bufferLength)
            val encrypted = encryptUnit(buffer)
            System.arraycopy(encrypted, 0, result, resultCurrentPosition, encrypted!!.size)
            resultCurrentPosition += encrypted.size
            currentPosition += bufferLength
        }
        return result
    } //    public static byte[] decryptV2(byte[] data) {
    //        if (data == null || data.length == 0) {
    //            return "".getBytes();
    //        }
    //        int dataLength = data.length;
    //
    //        if (dataLength <= DEFAULT_KEY_SIZE/8) {
    //            return decryptUnit(data);
    //        }
    //
    //        int blockCount = 0;
    //        if (dataLength % (DEFAULT_KEY_SIZE/8) != 0) {
    //            Log.e(TAG, "Invalid encrypted data length:" + dataLength);
    //            return null;
    //        }
    //
    //        blockCount = dataLength / (DEFAULT_KEY_SIZE/8);
    //
    //        byte[] result = new byte[blockCount * DEFAULT_BUFFERSIZE];
    //        int resultCurrentPosition = 0;
    //
    //        int currentPosition = 0;
    //        int bufferLength = DEFAULT_KEY_SIZE/8;
    //        while(currentPosition < dataLength) {
    //            byte[] buffer = new byte[bufferLength];
    //            System.arraycopy(data, currentPosition, buffer, 0, bufferLength);
    //            byte[] decrypted = decryptUnit(buffer);
    //            System.arraycopy(decrypted, 0, result, resultCurrentPosition, decrypted.length);
    //            resultCurrentPosition += decrypted.length;
    //            currentPosition += bufferLength;
    //        }
    //        return result;
    //    }
}
